﻿using System;

namespace Common
{
    /// <summary>
    /// 数据校验
    /// </summary>
    public class DataCheck
    {
        /// <summary>
        /// ModbsRTU CRC
        /// </summary>
        /// <param name="buf"> </param>
        /// <param name="len"> </param>
        /// <returns> </returns>
        public static UInt16 ModRTU_CRC(byte[] buf, int len)
        {
            UInt16 crc = 0xFFFF;

            for (int pos = 0; pos < len; pos++)
            {
                crc ^= (UInt16)buf[pos];          // XOR byte into least sig. byte of crc

                for (int i = 8; i != 0; i--)      // Loop over each bit
                {
                    if ((crc & 0x0001) != 0)        // If the LSB is set
                    {
                        crc >>= 1;                    // Shift right and XOR 0xA001
                        crc ^= 0xA001;
                    }
                    else                            // Else LSB is not set
                    {
                        crc >>= 1;                    // Just shift right
                    }
                }
            }
            // Note, this number has low and high bytes swapped, so use it
            // accordingly (or swap bytes)
            return crc;
        }

        /// <summary>
        /// ModbsRTU CRC
        /// </summary>
        /// <param name="buf"> </param>
        /// <returns> </returns>
        public static byte[] ModRTU_CRC(byte[] buf)
        {
            UInt16 crc = 0xFFFF;

            for (int pos = 0; pos < buf.Length; pos++)
            {
                crc ^= (UInt16)buf[pos];          // XOR byte into least sig. byte of crc

                for (int i = 8; i != 0; i--)      // Loop over each bit
                {
                    if ((crc & 0x0001) != 0)        // If the LSB is set
                    {
                        crc >>= 1;                    // Shift right and XOR 0xA001
                        crc ^= 0xA001;
                    }
                    else                            // Else LSB is not set
                    {
                        crc >>= 1;                    // Just shift right
                    }
                }
            }
            // Note, this number has low and high bytes swapped, so use it
            // accordingly (or swap bytes)
            return new byte[] { Convert.ToByte(crc & 0xff), Convert.ToByte(crc >> 8) };
        }
    }
}